Electron 自定义协议
· 阅读需 1 分钟
注册自定义协议,使用 loadURL 加载静态文件。
项目结构
| package.json
| ---app
| | main.js
| | preload.js
| \---renderer
| index.html
| renderer.js
| styles.css
Electron 版本
本文基于 electron@37.2.3
app/main.js
const { app, BrowserWindow, protocol, net } = require("electron");
const path = require("node:path");
const url = require("node:url");
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
mainWindow.loadURL(`app://renderer/index.html`);
}
// 首先声明自定义协议
protocol.registerSchemesAsPrivileged([
{
scheme: "app",
privileges: {
standard: true,
secure: true,
supportFetchAPI: true,
corsEnabled: true,
stream: true,
},
},
]);
app.whenReady().then(() => {
// 处理协议
protocol.handle("app", (request) => {
const filePath = request.url.slice("app://".length);
// mainWindow.loadURL(`app://index.html`) -> filePath = index.html/ 引起错误,需要再处理
return net.fetch(url.pathToFileURL(path.join(__dirname, filePath)).toString());
});
createWindow();
app.on("activate", function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on("window-all-closed", function () {
if (process.platform !== "darwin") app.quit();
});
处理协议 TIP
使用 URL 解析
protocol.handle("app", (request) => {
const filePath = request.url.slice("app://".length);
return net.fetch(url.pathToFileURL(path.join(__dirname, requestUrl.host, requestUrl.pathname)).toString());
});
使用 URL 解析可以处理 hash 路由文件, 如 app://renderer/index.html#about
SPA history 路由
需要像服务器一样重定向处理, 否则会报 404
app://renderer -> app://renderer/index.html
app://renderer/* -> app://renderer/index.html